//给定两个字符串 s 和 t 。返回 s 中包含 t 的所有字符的最短子字符串。如果 s 中不存在符合条件的子字符串，则返回空字符串 "" 。
//
// 如果 s 中存在多个符合条件的子字符串，返回任意一个。
//
//
//
// 注意： 对于 t 中重复字符，我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
//
//
//
// 示例 1：
//
//
//输入：s = "ADOBECODEBANC", t = "ABC"
//输出："BANC"
//解释：最短子字符串 "BANC" 包含了字符串 t 的所有字符 'A'、'B'、'C'
//
// 示例 2：
//
//
//输入：s = "a", t = "a"
//输出："a"
//
//
// 示例 3：
//
//
//输入：s = "a", t = "aa"
//输出：""
//解释：t 中两个字符 'a' 均应包含在 s 的子串中，因此没有符合条件的子字符串，返回空字符串。
//
//
//
// 提示：
//
//
// 1 <= s.length, t.length <= 10⁵
// s 和 t 由英文字母组成
//
//
//
//
// 进阶：你能设计一个在 o(n) 时间内解决此问题的算法吗？
//
//
//
//
// 注意：本题与主站 76 题相似（本题答案不唯一）：https://leetcode-cn.com/problems/minimum-window-
//substring/
//
// Related Topics 哈希表 字符串 滑动窗口 👍 101 👎 0


//leetcode submit region begin(Prohibit modification and deletion)
//? 相当于暴力了
function minWindow(s: string, t: string): string {

    /**
     * @param {string} s
     * @param {string} t
     * @return {string}
     */
    let tLen = t.length, sLen = s.length, mapS = new Map(), mapT = new Map();
    //? 1.每个字符计数
    for(let i = 0;i < tLen; i++) {
        mapT.set(t[i], (mapT.get(t[i]) || 0) + 1)
    }
    let l = 0, r = 0, len = Number.MAX_SAFE_INTEGER , ansL = -1, ansR = -1;
    //? 2.右边界持续滑动
    while(r < sLen) {
        //? 3.如果是目标字符则进行计数
        if(r < sLen && mapT.has(s[r])) {
            mapS.set(s[r], (mapS.get(s[r]) || 0) + 1)
        }
        //? 4.当收集满全部字符时开始缩小左边界
        while(check() && l <= r) {
            //? 记录最小连续的长度和左右
            if(r - l + 1 < len) {
                len = r - l + 1;
                ansL = l;
                ansR = r + 1;
            }
            if(mapT.has(s[l])) {
                mapS.set(s[l], (mapS.get(s[l]) || 0) - 1); //? 逐步缩小 减1
            }
            l++;
        }
        r++;
    }
    function check() {
        for(let [key, val] of mapT) {
            if((mapS.get(key) || 0) < val) return false;
        }
        return true;
    }
    return ansL === -1 ? "" : s.substring(ansL, ansR)


};
//leetcode submit region end(Prohibit modification and deletion)
